[Hadoop] 分布式文件系统HDFS 一

HDFS概述及设计目,什么是HDFS、HDFS前提和设计目标(HDFS 构成及工作原理解析,基本构成)、数据读写过程、集群架构(datanode、namenode、SecondaryNamenode)、HDFS HA简介、HDFS文件类型、HDFS副本机制

Posted by 李玉坤 on 2017-05-23

HDFS概述及设计目标

如果让我们自己来设计一个分布式文件系统,咋办?
下图是普通分布式文件系统

什么是HDFS

  • Hadoop实现了一个分布式文件系统( Hadoop Distributed File System) ,简称HDFS
  • 源自Google的GFS论文
  • 发表于2003年,HDFS是GFS的克隆版
  • 基于JAVA实现的一个分布式文件系统
  • 基于unix/linux
  • 是Hadoop最重要的核心组件
  • 支持顺序写入,而非随机定位读写

HDFS前提和设计目标

  • 存储超大文件
    HDFS适合存储大文件,单个文件大小通常在百MB以上
    HDFS适合存储海量文件,总存储量可达PB,EB级
  • 硬件容错
    基于普通机器搭建,硬件错误是常态而不是异常,因此错误检测和快速、自动的恢复是HDFS最核心的架构目标
  • 流式数据访问
    为数据批处理而设计,关注数据访问的高吞吐量
  • 简单的一致性模型
    一次写入,多次读取
    一个文件经过创建、写入和关闭之后就不需要改变
  • 本地计算
    将计算移动到数据附近

HDFS 构成及工作原理解析

基本构成

  • 数据块
    • 文件以块为单位进行切分存储,块通常设置的比较大(最小6M,默认128M)
    • 块越大,寻址越快,读取效率越高,但同时由于MapReduce任务也是以块为最小单位来处理,所以太大的块不利于于对数据的并行处理
    • 一个文件至少占用一个块(逻辑概念)
  • Namenode与Datanode
    • namenode 负责维护整个文件系统的信息,包括:整个文件树,文件的块分布信息,文件系统的元数据,数据复制策略等
    • datanode 存储文件内容,负责文件实际的读写操作,保持与namenode的通信,同步文件块信息
1
2
3
4
5
6
一个文件有多少个块:文件大小/块的大小
950m的单个文件,100m的块大小
总共块的个数:10
最后一个块的占用空间:50m,其他占用的空间为100m

块的大小在创建文件的时候可以指定,不指定则使用系统默认的设置,在Hadoop2.x里一个块对应的磁盘上的空间:128m

数据读写过程

文件写流程

hadoop fs -put xxx.log /

写过程是对客户端无感知的

FSDataOutputStream

  • Client调用FileSystem.create(filePath)方法,与NN进行【rpc】通信,检查其是否存在及是否有权限创建;假如不ok,就返回错误信息;假如ok,就创建一个新文件,不关联任何的block块,返回一个FSDataOutputStream对象。
  • Client调用FSDataOutputStream对象的write()方法,先将第一块的第一个副本的一个packet写到第一个DN,第一个副本写完;就传输给第二个DN,第二个副本写完;就传输给第三个DN,第三个副本写完。
  • 就返回一个ack packet确认包给第二个DN,第二个DN接收到第三个的ack packet确认包加上自身ok,就返回一个ack packet确认包给第一个DN,第一个DN接收到第二个DN的ack packet确认包加上自身ok,就返回ack packet确认包给FSDataOutputStream对象,标志第一个块 的第一个packeg 的3个副本写完。开始第二个packet写入,如此循环直至第一个块的三个副本写入完毕。
  • 然后余下的块依次这样写。
  • 当向文件写入数据完成后,Client调用FSDataOutputStream.close()方法,关闭输出流。
  • 再调用FileSystem.complete()方法,告诉NN该文件写入成功。

补充:

  • 切分block(可以指定两个参数;不知道则使用默认);然后给block分配写入的datanode。
  • 以pipeline方式写入;以packet(里面还有chunk数据单元(chunk里又check sum))形式写入;ack机制往上一层一层汇报写完一个chunk(以chunk为单元进行校验)。

文件读流程

  • Client调用FileSystem.open(filePath)方法,与NN进行【rpc】通信,返回该文件的部分或者全部的block列表,也就是返回FSDataInputStream对象。
  • Client调用FSDataInputStream对象read()方法;
    a.与第一个块最近的DN进行read,读取完成后,会check;假如ok,就关闭与当前DN的通信;假如失败,会记录失败块+DN信息,下次不会再读取;那么会去该块的第二个DN地址读取。
    b.然后去第二个块的最近的DN上通信读取,check后,关闭通信。
    c.假如block列表读取完成后,文件还未结束,就再次FileSystem会从NN获取该文件的下一批次的block列表。
    (感觉就是连续的数据流,对于客户端操作是透明无感知的)
  • Client调用FSDataInputStream.close()方法,关闭输入流。

总体流程图

集群架构



HDFS有主从架构。HDFS集群由一个NameNode组成,它是一个主服务器,管理文件系统名称空间并管理客户机对文件的访问。此外,还有许多datanode,通常每个节点一个,管理连接到它们运行的节点的存储。HDFS公开一个文件系统名称空间,并允许用户数据存储在文件中。在内部,文件被分割成一个或多个块,这些块存储在一组数据节点(datanode)中。NameNode执行文件系统操作,如打开、关闭和重命名文件和目录。它还记录块到datanode的映射。datanode负责服务来自文件系统客户端的读写请求。根据NameNode的指令,datanode还执行块的创建、删除和复制。


上图中

  • 1 个Master(NameNode/NN) 带 N个Slaves(DataNode/DN)
    HDFS/YARN/HBase其实都是一样的

  • 1个文件会被拆分成多个Block理解为:
    blocksize:128M
    130M ==> 2个Block: 128M 和 2M

  • Nanmenode:

    • 1)负责客户端请求的响应
    • 2)负责元数据(文件的名称、副本系数、Block存放的DN)的管理
  • Datenode:

    • 1)存储用户的文件对应的数据块(Block)
    • 2)要定期向NN发送心跳信息,汇报本身及其所有的block信息,健康状况

一个典型的部署是一台机器运行一个namenade,集群中的其他机器都运行一个DataNode。该体系结构不排除在同一台机器上运行多个DataNode,但在实际部署中却很少出现这种情况。

datanode

存储: 数据块、数据块校验
与NN通信:

  • a.每隔3s发送心跳包给 nn,我还活者
    dfs.heartbeat.interval 3

  • b.每隔一定的时间发生一次 blockreport
    dfs.blockreport.intervalMsec 21600000ms=6h
    dfs.datanode.directoryscan.interval 21600s=6h

namenode

作用:

  • Namespace管理:负责管理文件系统中的树状目录结构以及文件与数据块的映射关系
  • 块信息管理:负责管理文件系统中文件的物理块与实际存储位置的映射关系BlocksMap
  • 集群信息管理:机架信息,datanode信息
  • 集中式缓存管理:从Hadoop2.3 开始,支持datanode将文件缓存到内存中,这部分缓存通过NN集中管理

存储结构:

  • 内存: Namespace数据,BlocksMap数据,其他信息
  • 文件:
    • 已持久化的namespace数据:FsImage
    • 未持久化的namespace操作:Edits

启动过程:

  1. 开启安全模式:不能执行数据修改操作
  2. 加载fsimage
  3. 逐个执行所有Edits文件中的每一条操作将操作合并到fsimage,完成后生成一个空的edits文件
  4. 接收datanode发送来的心跳消息和块信息
  5. 根据以上信息确定文件系统状态
  6. 退出安全模式
  • 安全模式(safe mode):文件系统只接受读数据请求,而不接受删除、修改等变更请求

  • 什么情况下进入:NameNode主节点启动时,HDFS进入安全模式

  • 什么时候时候退出:系统达到安全标准时,HDFS退出安全模式

  • dfs.namenode.safemode.min.datanodes: 最小可用datanode数量

  • dfs.namenode.safemode.threshold-pct: 副本数达到最小要求的block占系统总block数的百分比

  • dfs.namenode.safemode.extension: 稳定时间

  • 相关命令:

  • hdfs dfsadmin -safemode get:查看当前状态

  • hdfs dfsadmin -safemode enter:进入安全模式

  • hdfs dfsadmin -safemode leave:强制离开安全模式

  • hdfs dfsadmin -safemode wait:一直等待直到安全模式结束

SecondaryNamenode

  • 存储: fsimage+editlog
  • 作用: 定期合并 fsimage+editlog文件作为新的fsimage,推送给NN,
  • 简称为checkpoint 检查点
    dfs.namenode.checkpoint.period 3600s
    dfs.namenode.checkpoint.txns 1000000

为了解决单点故障,只有NN,后来加了一个SNN角色 1小时的备份机制,虽然能够减轻单点故障,但是还会有风险,那60分元数据是恢复不了。

案例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 1 2 3 4  全备份 fsimage1
5 6 edit1
checkpoint1 : fsimage1+edit1==>fsimage2

fsimage2推送给nn
fsimage2
7 8 edit2
checkpoint2 : fsimage2+edit2==>fsimage3
edit3

NN下的文件
edits_0000000000000000306-0000000000000000307
edits_0000000000000000308-0000000000000000324
edits_inprogress_0000000000000000325
fsimage_0000000000000000307
fsimage_0000000000000000307.md5
fsimage_0000000000000000324
fsimage_0000000000000000324.md5

SNN下的文件
edits_0000000000000000302-0000000000000000303
edits_0000000000000000304-0000000000000000305
edits_0000000000000000306-0000000000000000307
edits_0000000000000000308-0000000000000000324
fsimage_0000000000000000307
fsimage_0000000000000000307.md5
fsimage_0000000000000000324
fsimage_0000000000000000324.md5

如何合并:
fsimage_0000000000000000307 + edits_0000000000000000308-0000000000000000324
==>fsimage_0000000000000000324

如图:

1.roll edit
2.传输 fsimage+edits
3.merge
4.传输 fsimage.ckpt to nn
5.回滚 fsimage.ckpt==》fsimage
edit.new==> edit

client写入与 NN+SNN 流程图

HDFS HA

  • Datanode: 通过数据冗余保证数据的可用性
  • Namenode: 在2.0以前存在SPOF风险,从2.0之后:
  1. 把name.dir指向NFS(Network File System)
  2. QJM 方案

HDFS文件类型-列式与行式存储

HDFS 支持任意文件格式主要分为列式与行式

HDFS文件类型-常用文件类型

HDFS文件类型-如何使用?

1
2
3
4
5
6
在hive中创建表的时候指定文件格式
ALTER TABLE table_name SET FILEFORMAT PARQUET;
CREATE TABLE table_name (x INT, y STRING) STORED AS PARQUET;

单独指定默认的文件格式
SET hive.default.fileformat=Orc

HDFS副本机制

HDFS支持传统的分层文件组织。用户或应用程序可以在这些目录中创建目录并存储文件。文件系统名称空间层次结构与大多数现有文件系统相似;可以创建和删除文件,将文件从一个目录移动到另一个目录,或者重命名文件。
NameNode维护文件系统名称空间。对文件系统名称空间或其属性的任何更改都由NameNode记录。应用程序可以指定由HDFS维护的文件的副本数量。一个文件的副本数量称为该文件的副本因子。这些信息由NameNode存储。

数据副本
HDFS被设计为在大型集群中的机器之间可靠地存储非常大的文件。它以块序列的形式存储每个文件。为了容错,复制文件的块。每个文件的块大小和复制因子都是可配置的。

除了最后一个块之外,文件中的所有块大小都相同。

应用程序可以指定文件的副本数量。副本因子可以在文件创建时指定,以后可以更改。HDFS中的文件只写一次(除了追加和截断之外),并且在任何时候都有一个写入者

NameNode就块的复制做出所有决定。它定期从集群中的每个datanode接收心跳和数据块报告。接收到心跳表示DataNode正常工作。块报表包含datanode上所有块的列表。

上图代表数据中心,两个机架,黄色代表客户端所在的节点(默认三个副本)

  • 第一个副本存放在同client的节点上面;client不是DN,就随机挑选一台磁盘不太慢 CPU不太繁忙的节点。
  • 第二个副本存放在不同第一个副本机架的随意一个节点。
  • 第三个副本存放在与第二个副本相同机架的另一个节点上。
  • 如果只有一个机架,则在不同节点存储;如果高于三个副本则高于三的随意挑选机架和节点。